﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Web.Hosting;
using System.Web;

namespace CodeUtils
{
    class IO
    {
        private const int BufferSize = 4096;
        public static FileSystemInfo GetFileSystemInfo(string path)
        {
            if (File.Exists(path))
            {
                return new FileInfo(path);
            }
            else if (Directory.Exists(path))
            {
                return new DirectoryInfo(path);
            }
            return null;
        }

        public static string ToValidFileName(string s, string invalidReplacement, string spaceReplacement)
        {
            StringBuilder sb = new StringBuilder(s);
            foreach (char invalidFileNameChar in Path.GetInvalidFileNameChars())
            {
                if (invalidReplacement != null)
                    sb.Replace(invalidFileNameChar.ToString(), invalidReplacement);
            }
            if (spaceReplacement != null)
                sb.Replace(" ", spaceReplacement);

            return sb.ToString();
        }

        public static string MapPath(string path)
        {
            if (Path.IsPathRooted(path))
            {
                return path;
            }
            else if (HostingEnvironment.IsHosted)
            {
                return HostingEnvironment.MapPath(path);
            }
            else if (VirtualPathUtility.IsAppRelative(path))
            {
                string physicalPath = VirtualPathUtility.ToAbsolute(path, "/");
                physicalPath = physicalPath.Replace('/', '\\');
                physicalPath = physicalPath.Substring(1);
                physicalPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, physicalPath);

                return physicalPath;
            }
            else
            {
                throw new Exception("Could not resolve non-rooted path.");
            }
        }
        

        public static void WriteStream(Stream sourceStream, Stream destinationStream)
        {
            WriteStream(sourceStream, destinationStream, BufferSize);
        }

        public static void WriteStream(Stream sourceStream, Stream destinationStream, int bufferSize)
        {
            if (sourceStream == null)
                throw new ArgumentNullException("sourceStream");

            if (destinationStream == null)
                throw new ArgumentNullException("destinationStream");

            byte[] buffer = new byte[bufferSize];

            int bytesRead;

            // while read on the stream continues to return data,
            // write the data into the memorystream
            while ((bytesRead = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                destinationStream.Write(buffer, 0, bytesRead);
            }
        }

        public static byte[] ReadAllBytes(Stream stream)
        {
            byte[] data = new byte[stream.Length - stream.Position];

            stream.Read(data, (int)stream.Position, data.Length);

            return data;
        }
    }
}
